package com.lmabbe.common.datasources;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.lmabbe.common.datasources.config.DataSourcesProperties;
import com.lmabbe.common.datasources.core.CustomIdGenerator;
import com.lmabbe.common.datasources.core.MyMetaObjectHandler;
import com.lmabbe.common.datasources.interceptor.DataScopeInterceptor;
import com.lmabbe.common.datasources.plugin.TenantMasterSlaveAutoRoutingPlugin;
import lombok.RequiredArgsConstructor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.InvocationTargetException;

/**
 * @author lmabbe
 * @data 2021/3/22 22:13
 */
@Configuration
@EnableConfigurationProperties(DataSourcesProperties.class)
@RequiredArgsConstructor
@MapperScan(value = {"com.gitee.sunchenbin.mybatis.actable.dao.*", "com.lmabbe.common.datasources.mapper"})
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
@ConditionalOnProperty(prefix = "lmabbe.datasources", name = "enable", havingValue = "true", matchIfMissing = true)
public class LmabbeDataSourcesAutoConfiguration {

    private final DataSourcesProperties dataSourcesProperties;
    private final ApplicationContext applicationContext;

    /**
     * 开启分页
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "lmabbe.datasources", name = "enable-page", havingValue = "true", matchIfMissing = true)
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new DataScopeInterceptor(applicationContext));
        //注入分页
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    /**
     * 注入
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "lmabbe.datasources", name = "enable-page", havingValue = "true", matchIfMissing = true)
    public IdentifierGenerator identifierGenerator() {
        System.out.println("开启是否注入ID");
        if (dataSourcesProperties.isUseHuToolSnowflakeId()) {
            return new CustomIdGenerator(dataSourcesProperties);
        } else {
            Class<? extends IdentifierGenerator> idGenerateClass = dataSourcesProperties.getIdGenerateClass();
            if (null == idGenerateClass) {
                return new CustomIdGenerator(dataSourcesProperties);
            } else {
                try {
                    return idGenerateClass.getDeclaredConstructor().newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }

    }

    @Bean
    @ConditionalOnMissingBean
    public MetaObjectHandler metaObjectHandler() {
        System.out.println("注入数据");
        return new MyMetaObjectHandler();
    }


    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "lmabbe.datasources", name = "is-platform", havingValue = "false")
    public TenantMasterSlaveAutoRoutingPlugin tenantMasterSlaveAutoRoutingPlugin() {
        return new TenantMasterSlaveAutoRoutingPlugin(applicationContext);
    }

}
